/**
 * Game
 * When intantiated, will run the game (using run() method).
 * @author Alan Marvel 
 */
public class Game
{
	private final int PARTY_SIZE = 4, START_LOCATION = 0;
	
	private PartyLeader user;
	private PartyMember[] party;
	private Wagon wagon;
	private Equipment eq;

	private MainMenu mm;
	private PlayerConfiguration pc;
	private CreditScreen cs;
	private StoreUI sui;
	
    /**
     * Starts the game session.
     */
	public void run()
	{
		runMainMenu();
		runPlayerConfiguration();
		/*System.out.println(user.getPlayerName());
		System.out.println(user.getMoney());
		System.out.println(party[0].getName());
		System.out.println(party[1].getName());
		System.out.println(party[2].getName());
		System.out.println(party[3].getName());
		System.out.println(wagon.getLocation());
		System.out.println(wagon.getPace());
		System.out.println(wagon.getRations()); */
		runFirstStore(new Store(0));
		
		
		//Put InfoDisplay up
		/*try
		{
			InfoDisplay test = new InfoDisplay(user, party, wagon, eq);
			test.setVisible(true);
			while(true);
		} catch(Exception e)
		{
			e.printStackTrace();
		}*/
		
		runCreditScreen();
	}
	
    /**
     * Loads up Main Menu GUI and continues when "Start Game" button is pressed.
     */
	private void runMainMenu()
	{
		try
		{
			mm = new MainMenu();
			mm.setVisible(true);
			while (!mm.hasFinished())
				Thread.sleep(10);
			mm.setVisible(false);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	} //end runMainMenu
	
    /**
	 * Loads up Player Configuration GUI and continues when information is entered correctly.
     * Initializes PartyLeader, four PartyMember, and Wagon objects.
	 * Sets rations chosen, pace chosen and initial location for Wagon.
	 * Sets name and profession for PartyLeader
	 * Sets name for each PartyMember
     */
	private void runPlayerConfiguration()
	{
		try
		{
			pc = new PlayerConfiguration();
			pc.setVisible(true);
			while (!pc.hasFinished())
				Thread.sleep(10);
			
			String[] names = pc.getNames(); //retrieve array of names, 0 being PartyLeader and the rest PartyMember names
			wagon = new Wagon(pc.getPace(), START_LOCATION, pc.getRations());
			user = new PartyLeader(names[0], pc.getProfession());
			party = new PartyMember[PARTY_SIZE];
			eq = new Equipment();
			for (int i = 0; i < PARTY_SIZE; i++)
			{
				party[i] = new PartyMember(names[i + 1]);
			}
			pc.setVisible(false);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	} //end runPlayerConfiguration
	
	/**
	 * Loads a StoreUI based on the sent-in store. Displays quantities of items and prices and allows the user to purchase items that they can afford/hold in the wagon.
	 * @param s Store instance that the UI is based on.
	 */
	private void runFirstStore(Store s)
	{
		try
		{
			boolean done = false;
			sui = new StoreUI(s);
			sui.setVisible(true);
			while(!done)
			{
				//System.err.println("In first loop");
				while(!sui.hasFinished())
					Thread.sleep(1);
				//System.err.println("Finished");
				int cost = calcTotalCost(sui.getQuants(), s);
				int weight = calcTotalWeight(sui.getQuants());
				//System.err.println("Cost: " + cost + " Weight:" + weight);
				
				if(cost <= user.getMoney() && Equipment.MAX_WEIGHT - eq.getWeight() >= weight) //check that there is space in the equipment (Max weight - eq.getWeight() < weight)
				{
					user.addMoney(-cost);
					eq.addItems(sui.getQuants());
					done = true;
				}
				else
				{
					sui.setHasFinished(false);
					//System.err.println("Something is wrong.");
				}
			}
			sui.setVisible(false);
		} 
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * Helper function that calculates the cost of an order in the StoreUI
	 * @param a List of the desired quantities of items
	 * @param s The store the items are being purchased from
	 * @return Total cost of the items
	 */
	private int calcTotalCost(int[] a, Store s)
	{
		int cost = 0;
		for(int i = 0; i < a.length; i++)
			cost += a[i] * (s.getCosts())[i];
		
		return cost;
	}
	
	/**
	 * Helper function that calculates the weight of an order in the StoreUI
	 * @param a List of the desired quantities of items
	 * @return Weight of the desired items
	 */
	private int calcTotalWeight(int[] a)
	{
		int weight = 0;
		for(int i = 0; i < a.length; i++)
			weight += a[i] * (Store.Item_List)[i].getWeight();
		
		return weight;
	}
	
    /**
     * Loads Credit Screen GUI, must press "X" to close program.
     */
	private void runCreditScreen()
	{
		try {
			cs = new CreditScreen();
			cs.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	} //end runCreditScreen
	
	public static void main(String[] args)
	{
		Game game = new Game();
		game.run();
	}
}
